package cn.inyaa.admin.blog.dao.dsl.impl;

import cn.inyaa.admin.blog.bean.InyaaBlog;
import cn.inyaa.admin.blog.bean.QInyaaBlog;
import cn.inyaa.admin.blog.bean.QInyaaType;
import cn.inyaa.admin.blog.dao.dsl.InyaaBlogDslDao;
import cn.inyaa.admin.blog.dto.InyaaBlogDto;
import cn.inyaa.admin.blog.vo.InyaaBlogArchiveVo;
import cn.inyaa.admin.blog.vo.InyaaBlogVo;
import cn.inyaa.admin.sys.bean.QInyaaSysUser;
import com.querydsl.core.QueryResults;
import com.querydsl.core.types.Projections;
import com.querydsl.core.types.dsl.Expressions;
import com.querydsl.core.types.dsl.StringTemplate;
import com.querydsl.jpa.impl.JPAQuery;
import com.querydsl.jpa.impl.JPAQueryFactory;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Repository;

import java.time.format.DateTimeFormatter;
import java.util.List;

@Repository
@RequiredArgsConstructor
public class InyaaBlogDslDaoImpl implements InyaaBlogDslDao {

    private final JPAQueryFactory jpaQueryFactory;

    @Override
    public Page<InyaaBlogVo> findBlogListPage(InyaaBlogDto req) {
        Pageable page = PageRequest.of(req.getPage(), req.getSize());
        QInyaaBlog qBean = QInyaaBlog.inyaaBlog;
        QInyaaType qInyaaType = QInyaaType.inyaaType;
        QInyaaSysUser qInyaaSysUser = QInyaaSysUser.inyaaSysUser;
        JPAQuery<InyaaBlogVo> jpaQuery = jpaQueryFactory.select(Projections.bean(InyaaBlogVo.class,
                qBean.id, qBean.summary, qBean.title, qBean.status, qBean.isHot,
                qBean.views, qBean.comments, qBean.cover, qInyaaType.id.as("typeId"), qInyaaType.name.as("typeName"),
                qBean.isComment, qBean.updateTime, qBean.createTime, qInyaaSysUser.name.as("author"))).from(qBean);
        jpaQuery.leftJoin(qInyaaSysUser).on(qInyaaSysUser.id.eq(qBean.userId));
        jpaQuery.leftJoin(qInyaaType).on(qInyaaType.id.eq(qBean.typeId));
        if (req.getTypeId() != null) {
            jpaQuery.where(qBean.typeId.eq(req.getTypeId()));
        }
        if (req.getCreateTime() != null) {
            StringTemplate eqTime = Expressions.stringTemplate("DATE_FORMAT({0},'%Y-%m-%d')", req.getCreateTime());
            String queryDate = req.getCreateTime().format(DateTimeFormatter.ISO_DATE);
            jpaQuery.where(eqTime.eq(queryDate));
        }
        if (StringUtils.isNoneBlank(req.getTitle())) {
            jpaQuery.where(qBean.title.like(req.getTitle()));
        }
        if (req.getStatus() != null) {
            jpaQuery.where(qBean.status.eq(req.getStatus()));
        }
        if (req.getTypeId() != null) {
            jpaQuery.where(qBean.typeId.eq(req.getTypeId()));
        }
        if (req.getIsHot() != null) {
            jpaQuery.where(qBean.isHot.eq(req.getIsHot()));
        }
        jpaQuery.orderBy(qBean.createTime.desc());
        jpaQuery.offset(page.getOffset()).limit(page.getPageSize());
        QueryResults<InyaaBlogVo> queryResults = jpaQuery.fetchResults();
        return new PageImpl<>(queryResults.getResults(), page, queryResults.getTotal());
    }

    @Override
    public List<InyaaBlogArchiveVo> findArchiveList() {
        QInyaaBlog qBean = QInyaaBlog.inyaaBlog;
        StringTemplate dateFmt = Expressions.stringTemplate("DATE_FORMAT({0},'%Y-%m-01 00:00:00')", qBean.createTime);
        JPAQuery<InyaaBlogArchiveVo> jpaQuery = jpaQueryFactory
                .select(Projections.bean(InyaaBlogArchiveVo.class, dateFmt.as("archiveDate")))
                .from(qBean)
                .groupBy(dateFmt)
                .orderBy(dateFmt.desc());
        return jpaQuery.fetch();
    }

    @Override
    public List<InyaaBlog> findByArchiveDate(String archiveDate) {
        QInyaaBlog qBean = QInyaaBlog.inyaaBlog;
        StringTemplate dateFmt = Expressions.stringTemplate("DATE_FORMAT({0},'%Y-%m-01 00:00:00')", qBean.createTime);
        StringTemplate req = Expressions.stringTemplate("DATE_FORMAT({0},'%Y-%m-01 00:00:00')", archiveDate);
        JPAQuery<InyaaBlog> jpaQuery = jpaQueryFactory
                .select(qBean)
                .from(qBean)
                .where(dateFmt.eq(req));
        return jpaQuery.fetch();
    }
}
